package com.yanqu.road.server.manager.activity.shuihuyezipai;

import com.yanqu.road.entity.activity.shuihuyezipai.*;
import com.yanqu.road.entity.activity.shuihuyezipai.config.ShuiHuYeZiCardActivityConfig;
import com.yanqu.road.entity.log.LogShuiHuYeZiCardPVPBattlerRoundRecord;
import com.yanqu.road.entity.log.LogShuiHuYeZiCardPVPUserInfo;
import com.yanqu.road.logic.pb.PlayerBasePb;
import com.yanqu.road.utils.YanQuMessageUtils;
import com.yanqu.road.pb.activity.ShuiHuYeZiCardProto;
import com.yanqu.road.pb.player.PlayerProto;
import com.yanqu.road.server.logic.MessageHelper;
import com.yanqu.road.server.manager.user.CrossUserMgr;
import com.yanqu.road.server.manger.AbstractShuiHuYeZiCardRoom;
import com.yanqu.road.server.manger.ShuiHuYeZiCardCommonMgr;
import com.yanqu.road.server.protocol.ClientProtocol;
import com.yanqu.road.server.protocol.GameErrorCode;
import com.yanqu.road.server.protocol.GameProtocol;
import com.yanqu.road.utils.date.DateHelper;

import java.util.*;

/**
 * @Description 水浒叶子牌  pvp 房间
 * @Author cwq
 * @Data 2021/12/8 9:58
 */
public class ShuiHuYeZiCardPVPRoom extends AbstractShuiHuYeZiCardRoom {

    private ShuiHuYeZiCardUserBattleInfo player1;

    private ShuiHuYeZiCardUserBattleInfo player2;

    private Map<Long, PlayerProto.PlayerBaseTempMsg> userMap = new HashMap<>();

    /**
     * 活动配置
     */
    private ShuiHuYeZiCardActivityConfig activityConfig;

    /**
     * 本回合出牌截止时间 pvp 才有  ms
     */
    private long roundEndTime;

    /**
     * 玩家初始手牌 结束后，打印日志用
     */
    private Map<Long, LogShuiHuYeZiCardPVPUserInfo> userLogMap = new HashMap<>();


    public ShuiHuYeZiCardPVPRoom(ShuiHuYeZiCardRoomData roomInfo, ShuiHuYeZiCardUserBattleInfo player1, ShuiHuYeZiCardUserBattleInfo player2) {
        super(roomInfo);
        this.player1 = player1;
        this.player2 = player2;
    }

    @Override
    public boolean startGame() {
        ShuiHuYeZiCardActivityConfig tempActivityConfig = ShuiHuYeZiCardActivityConfigMgr.getActivityConfig(player1.getActivityId());
        if(tempActivityConfig == null){
            getLogger().error("水浒卡牌缺少配置 activityId :{},创建不了房间",player1.getActivityId() );
            return false;
        }
        activityConfig = tempActivityConfig;

        List<List<Integer>> cardList = dealCard(activityConfig);

        Map<Integer, ShuiHuYeZiCardBattleCard> cardMap1 = ShuiHuYeZiCardCommonMgr.createBattleCard(cardList.get(0),player1.getUserCardMap());
        Map<Integer,ShuiHuYeZiCardBattleCard> cardMap2 = ShuiHuYeZiCardCommonMgr.createBattleCard(cardList.get(1),player2.getUserCardMap());

        getRoomInfo().getUserCardMap().put(player1.getUserId(),cardMap1);
        getRoomInfo().getUserCardMap().put(player2.getUserId(),cardMap2);

        touchBuff(activityConfig);

        getRoomInfo().setStartTime(DateHelper.getCurrentTime());
        roundEndTime = getRoomInfo().getStartTime() +(activityConfig.SHUIHUYEZICARD_ROUND_TIME* DateHelper.SECOND_MILLIONS);
        // 开局动画
        roundEndTime += activityConfig.animationList.get(0);
        // 日志
        userLogMap.put(player1.getUserId(),new LogShuiHuYeZiCardPVPUserInfo(player1.getActivityId(),player1.getRoomType(),ShuiHuYeZiCardCommonMgr.createLogShuiHuYeZiCardUserCardList(getRoomInfo().getUserCardMap().get(player1.getUserId()))));
        userLogMap.put(player2.getUserId(),new LogShuiHuYeZiCardPVPUserInfo(player2.getActivityId(),player2.getRoomType(),ShuiHuYeZiCardCommonMgr.createLogShuiHuYeZiCardUserCardList(getRoomInfo().getUserCardMap().get(player2.getUserId()))));

        // 广播给 玩家房间信息

        ShuiHuYeZiCardProto.BroadcastShuiHuYeZiCardRespMsg.Builder broadcastMsg = ShuiHuYeZiCardProto.BroadcastShuiHuYeZiCardRespMsg.newBuilder();

        userMap.put(player1.getUserId(), PlayerBasePb.parsePlayerBaseTempMsg(CrossUserMgr.getUserBaseInfo(player1.getUserId())).build());
        userMap.put(player2.getUserId(), PlayerBasePb.parsePlayerBaseTempMsg(CrossUserMgr.getUserBaseInfo(player2.getUserId())).build());

        ShuiHuYeZiCardProto.ShuiHuYeZiCardRoomInfo.Builder roomInfo = builderShuiHuYeZiCardRoomInfo(0);
        broadcastMsg.setType(2);
        broadcastMsg.setRoomInfo(roomInfo);

        ShuiHuYeZiCardProto.ShuiHuYeZiCardMatchSuccessGameToServerMsg.Builder matchSuccessMsg1 = ShuiHuYeZiCardProto.ShuiHuYeZiCardMatchSuccessGameToServerMsg.newBuilder();
        matchSuccessMsg1.setBroadcast(broadcastMsg);
        matchSuccessMsg1.setRoomType(player1.getRoomType());
        MessageHelper.sendPacket(player1.getServerId(), player1.getUserId() , YanQuMessageUtils.buildMessage(GameProtocol.S_SHUIHUYEZICARD_MATCH_SUCCESS_FROM_CROSS, matchSuccessMsg1));

        ShuiHuYeZiCardProto.ShuiHuYeZiCardMatchSuccessGameToServerMsg.Builder matchSuccessMsg2 = ShuiHuYeZiCardProto.ShuiHuYeZiCardMatchSuccessGameToServerMsg.newBuilder();
        matchSuccessMsg2.setBroadcast(broadcastMsg);
        matchSuccessMsg2.setRoomType(player2.getRoomType());
        MessageHelper.sendPacket(player2.getServerId(), player2.getUserId() , YanQuMessageUtils.buildMessage(GameProtocol.S_SHUIHUYEZICARD_MATCH_SUCCESS_FROM_CROSS, matchSuccessMsg2));
        return true;
    }


    public void playCard(long userId,long serverId, int id, int round) {
        synchronized (this){
            int ret = playCard(userId,id,round);
            ShuiHuYeZiCardProto.ShuiHuYeZiCardPlayCardRespMsg.Builder builder = ShuiHuYeZiCardProto.ShuiHuYeZiCardPlayCardRespMsg.newBuilder();
            builder.setRet(ret);
            MessageHelper.sendPacket(serverId, userId , YanQuMessageUtils.buildMessage(ClientProtocol.U_SHUIHUYEZICARD_PLAY_CARD,builder));
            // 通知对方对方出牌了
            if(ret == 0){
                if(player1.getCurPlayCard() != null && player2.getCurPlayCard() != null){
                    // 双方都出牌了
                    pvpRoundEnd();
                }else {
                    ShuiHuYeZiCardProto.BroadcastShuiHuYeZiCardRespMsg.Builder broadcast0 = ShuiHuYeZiCardProto.BroadcastShuiHuYeZiCardRespMsg.newBuilder();
                    broadcast0.setType(0);
                    broadcast0.setRound(getRoomInfo().getRound());
                    // 对方 targetId
                    ShuiHuYeZiCardUserBattleInfo targetInfo = getTargetUserBattleInfo(userId);
                    MessageHelper.sendPacket(targetInfo.getServerId(), targetInfo.getUserId() , YanQuMessageUtils.buildMessage(ClientProtocol.U_SHUIHUYEZICARD_BROADCAST,broadcast0));
                }
            }
        }
    }

    @Override
    public int playCard(long userId, int id, int round) {
        if(getRoomInfo().getRound() != round){
            return GameErrorCode.E_SHUIHUYEZICARD_ACTIVITY_ROUND_ERROR;
        }
        ShuiHuYeZiCardUserBattleInfo userBattleInfo = getShuiHuYeZiCardUserBattleInfo(userId);
        if(userBattleInfo.getCurPlayCard() != null){
            return GameErrorCode.E_SHUIHUYEZICARD_ACTIVITY_THE_ROUND_PLAYED;
        }

        Map<Integer, ShuiHuYeZiCardBattleCard> userCardMap = getRoomInfo().getUserCardMap().get(userId);

        ShuiHuYeZiCardBattleCard cardBattleCard = userCardMap.remove(id);
        if(cardBattleCard == null){
            return GameErrorCode.E_SHUIHUYEZICARD_ACTIVITY_HAVE_NOT_THE_CARD;
        }
        userBattleInfo.setCurPlayCard(cardBattleCard);
        return 0;
    }

    @Override
    public ShuiHuYeZiCardBattleCard autoPlayCard() {
        synchronized (this) {
            if (isOver() || DateHelper.getCurrentTime() < getRoundEndTime()) {
                // 游戏结束 或者 该回合未结束
                return null;
            }
            // 应该 防止自动出牌的时候 双方出牌了
            autoPlay(player1);
            autoPlay(player2);
            pvpRoundEnd();
        }
        return null;
    }

    @Override
    public boolean isOver() {
        if (player1.getCurPlayCard() == null && player2.getCurPlayCard() == null) {
            for (Map<Integer, ShuiHuYeZiCardBattleCard> userCardMap : getRoomInfo().getUserCardMap().values()) {
                if (userCardMap.size() == 0) {
                    return true;
                }
            }
        }
        return false;
    }

    /**
     * pvp 回合结算
     */
    private void pvpRoundEnd(){
        int buffId = getRoomInfo().getBuffId();
        int curRound = getRoomInfo().getRound();
        long winnerId = battle(player1.getCurPlayCard(),player1.getUserId(),player1.isAutoPlay(),player2.getCurPlayCard(),player2.getUserId(),player2.isAutoPlay());
        // 回合结束
        boolean isChangBuff = roundOver(activityConfig);

        roundEndTime = DateHelper.getCurrentTime() + (activityConfig.SHUIHUYEZICARD_ROUND_TIME * DateHelper.SECOND_MILLIONS);

        roundEndTime += activityConfig.animationList.get(1);
        if(isChangBuff){
            roundEndTime += activityConfig.animationList.get(2);
        }

        ShuiHuYeZiCardProto.BroadcastShuiHuYeZiCardRespMsg.Builder broadcastType1 = builderRoundShuiHuYeZiCardRespMsg(curRound,winnerId,player1.getUserId(),player1.getCurPlayCard(),player2.getUserId(),player2.getCurPlayCard(),roundEndTime,buffId,2);
        // 广播 出牌情况
        MessageHelper.sendPacket(player1.getServerId(), player1.getUserId() , YanQuMessageUtils.buildMessage(ClientProtocol.U_SHUIHUYEZICARD_BROADCAST, broadcastType1));
        MessageHelper.sendPacket(player2.getServerId(), player2.getUserId() , YanQuMessageUtils.buildMessage(ClientProtocol.U_SHUIHUYEZICARD_BROADCAST, broadcastType1));
        // 清理出过的牌
        player1.setCurPlayCard(null);
        player1.setAutoPlay(false);

        player2.setCurPlayCard(null);
        player2.setAutoPlay(false);
        endGame();
    }

    /**
     * 发送消息
     * @param userId
     * @param expressId 表情id
     * @return
     */
    public synchronized int sendMsg(long userId,int expressId){
        int now = DateHelper.getCurrentSecond();
        ShuiHuYeZiCardUserBattleInfo userBattleInfo = getShuiHuYeZiCardUserBattleInfo(userId);
        if(now - userBattleInfo.getSendMsgTime() > 60){
            userBattleInfo.setSendMsgTime(now);
            userBattleInfo.setSendMsgTimes(0);
        }
        if(userBattleInfo.getSendMsgTimes() >= 3){
            return GameErrorCode.E_SHUIHUYEZICARD_ACTIVITY_SEND_MSG_TOO_OFTEN;
        }
        userBattleInfo.setSendMsgTimes(userBattleInfo.getSendMsgTimes() + 1);

        ShuiHuYeZiCardUserBattleInfo targetUserBattleInfo = getTargetUserBattleInfo(userId);
        ShuiHuYeZiCardProto.BroadcastShuiHuYeZiCardRespMsg.Builder broadcast = ShuiHuYeZiCardProto.BroadcastShuiHuYeZiCardRespMsg.newBuilder();
        broadcast.setType(5);
        broadcast.setExpresssId(expressId);
        MessageHelper.sendPacket(targetUserBattleInfo.getServerId(), targetUserBattleInfo.getUserId() , YanQuMessageUtils.buildMessage(ClientProtocol.U_SHUIHUYEZICARD_BROADCAST, broadcast));
        return 0;
    }


    @Override
    public void endGame() {
        if(!isOver()){
            return;
        }
        // 加日志
        ShuiHuYeZiCardActivityLogMgr.addLogShuiHuYeZiCardPVPBattlerRoundRecord(new LogShuiHuYeZiCardPVPBattlerRoundRecord(getRoomInfo().getStartTime(),userLogMap,getRoomInfo().getRecordList(),getWinnerId(),DateHelper.getCurrentSecond()));

        ShuiHuYeZiCardActivityBattleMgr.pvpRoomMap.remove(player1.getUserId());
        ShuiHuYeZiCardActivityBattleMgr.pvpRoomMap.remove(player2.getUserId());
        ShuiHuYeZiCardActivityBattleMgr.pvpRoomList.remove(this);

        int playerLevel1 = ShuiHuYeZiCardCommonMgr.getLevel(activityConfig,player1.getRankScore());
        int playerLevel2 = ShuiHuYeZiCardCommonMgr.getLevel(activityConfig,player2.getRankScore());
        // 对位差
        int diffLevel1 = (playerLevel1 >= playerLevel2 ? 0 : playerLevel2 - playerLevel1);
        MessageHelper.sendPacket(player1.getServerId(), player1.getUserId() , YanQuMessageUtils.buildMessage(GameProtocol.S_SHUIHUYEZICARD_SETTLEMENT_FROM_CROSS, builderShuiHuYeZiCardSettlementCrossToGameMsg(player1,diffLevel1)));
        int diffLevel2 = (playerLevel2 >= playerLevel1 ? 0 : playerLevel1 - playerLevel2);
        MessageHelper.sendPacket(player2.getServerId(), player2.getUserId() , YanQuMessageUtils.buildMessage(GameProtocol.S_SHUIHUYEZICARD_SETTLEMENT_FROM_CROSS, builderShuiHuYeZiCardSettlementCrossToGameMsg(player2,diffLevel2)));
    }


    public long getRoundEndTime() {
        return roundEndTime;
    }


    public ShuiHuYeZiCardUserBattleInfo getShuiHuYeZiCardUserBattleInfo(long userId){
        if(player1.getUserId() == userId){
            return player1;
        }else {
            return player2;
        }
    }

    public ShuiHuYeZiCardUserBattleInfo getTargetUserBattleInfo(long userId){
        if(player1.getUserId() != userId){
            return player1;
        }else {
            return player2;
        }
    }

    public Map<Long, PlayerProto.PlayerBaseTempMsg> getUserMap() {
        return userMap;
    }


    public ShuiHuYeZiCardProto.ShuiHuYeZiCardSettlementCrossToGameMsg.Builder builderShuiHuYeZiCardSettlementCrossToGameMsg(ShuiHuYeZiCardUserBattleInfo userBattleInfo,int diffLevel){
        ShuiHuYeZiCardProto.ShuiHuYeZiCardSettlementCrossToGameMsg.Builder settlementCrossToGameMsg = ShuiHuYeZiCardProto.ShuiHuYeZiCardSettlementCrossToGameMsg.newBuilder();
        settlementCrossToGameMsg.setStartTime(getRoomInfo().getStartTime());
        settlementCrossToGameMsg.setEndTime(DateHelper.getCurrentSecond());
        settlementCrossToGameMsg.setDiffLevel(diffLevel);
        settlementCrossToGameMsg.setIsWin(isWin(userBattleInfo.getUserId()));
        // 我方剩余卡牌数量
        settlementCrossToGameMsg.setRankScore(userBattleInfo.getRankScore());
        settlementCrossToGameMsg.setRemainCardNum(getRoomInfo().getUserCardMap().get(userBattleInfo.getUserId()).size());
        settlementCrossToGameMsg.setRoomId(userBattleInfo.getRoomType());
        // 对手
        ShuiHuYeZiCardUserBattleInfo targetInfo = getTargetUserBattleInfo(userBattleInfo.getUserId());
        settlementCrossToGameMsg.setTargetId(targetInfo.getUserId());
        settlementCrossToGameMsg.setTargetRemainCardNum(getRoomInfo().getUserCardMap().get(targetInfo.getUserId()).size());
        settlementCrossToGameMsg.setPlayerInfo(PlayerBasePb.parsePlayerBaseTempMsg(CrossUserMgr.getUserBaseInfo(targetInfo.getUserId())));
        return settlementCrossToGameMsg;
    }

    /**
     * @param userId
     * @return
     */
    @Override
    public ShuiHuYeZiCardProto.ShuiHuYeZiCardRoomInfo.Builder builderShuiHuYeZiCardRoomInfo(long userId){
        ShuiHuYeZiCardUserBattleInfo targetUserBattleInfo = getTargetUserBattleInfo(userId);
        Map<Long, Map<Integer, ShuiHuYeZiCardBattleCard>> userCardMap = new HashMap<>();
        if(targetUserBattleInfo.getCurPlayCard() != null){
            // 下发对手手牌的时候 需要加上对手这回合出的手牌
            Map<Integer, ShuiHuYeZiCardBattleCard> map = new HashMap<>(getRoomInfo().getUserCardMap().get(targetUserBattleInfo.getUserId()));
            map.put(targetUserBattleInfo.getCurPlayCard().getId(),targetUserBattleInfo.getCurPlayCard());
            userCardMap.put(targetUserBattleInfo.getUserId(),map);

            userCardMap.put(userId,new HashMap<>(getRoomInfo().getUserCardMap().get(userId)));
        }else {
            userCardMap = getRoomInfo().getUserCardMap();
        }
        ShuiHuYeZiCardUserBattleInfo userBattleInfo = getShuiHuYeZiCardUserBattleInfo(userId);

        ShuiHuYeZiCardProto.ShuiHuYeZiCardRoomInfo.Builder roomInfo = ShuiHuYeZiCardCommonMgr.builderShuiHuYeZiCardRoomInfo(this,userCardMap,getRoundEndTime(),getUserMap(),userBattleInfo.getRoomType());
        for (ShuiHuYeZiCardProto.ShuiHuYeZiCardUserBattleInfo.Builder builder : roomInfo.getBattleInfoListBuilderList()){
            ShuiHuYeZiCardUserBattleInfo item = getShuiHuYeZiCardUserBattleInfo(builder.getUserId());
            ShuiHuYeZiCardBattleCard battleCard = item.getCurPlayCard();
            if(battleCard != null ){
                // 该玩家已出牌
                if(item.getUserId() == userId){
                    // 自己才能看到自己出的牌
                    builder.setPlayCard(ShuiHuYeZiCardCommonMgr.builderShuiHuYeZiCardCardInfo(battleCard));
                }else {
                    builder.setPlayCard(ShuiHuYeZiCardProto.ShuiHuYeZiCardCardInfo.newBuilder().setId(-1));
                }
            }
            builder.setRankScore(item.getRankScore());
        }
        return roomInfo;
    }

    /**
     * 玩家加载房间数据
     * @param userId
     */
    public void loadGame(long userId,long serverId){
        // 下发正在开启的房间
        ShuiHuYeZiCardProto.ShuiHuYeZiCardLoadRoomRespMsg.Builder builder = ShuiHuYeZiCardProto.ShuiHuYeZiCardLoadRoomRespMsg.newBuilder();
        synchronized (this){
            // 防止 组装完消息后，房间数据发生变动 所以加了锁
            ShuiHuYeZiCardProto.ShuiHuYeZiCardRoomInfo.Builder roomInfo = builderShuiHuYeZiCardRoomInfo(userId);
            builder.setRoomInfo(roomInfo);
            builder.setRet(0);
            MessageHelper.sendPacket(serverId, userId , YanQuMessageUtils.buildMessage(ClientProtocol.U_SHUIHUYEZICARD_LOAD_PVP_ROOM,builder));
        }
    }

    /**
     * 自动出牌
     * @param userBattleInfo
     */
    private void autoPlay(ShuiHuYeZiCardUserBattleInfo userBattleInfo){
        if(userBattleInfo.getCurPlayCard() == null){
            Map<Integer, ShuiHuYeZiCardBattleCard> userCardMap = getRoomInfo().getUserCardMap().get(userBattleInfo.getUserId());

            // 随机出牌
            List<ShuiHuYeZiCardBattleCard> list = new ArrayList<>(userCardMap.values());
            ShuiHuYeZiCardBattleCard card = list.get(getRandom().nextInt(list.size()));

            userCardMap.remove(card.getId());
            userBattleInfo.setCurPlayCard(card);
            userBattleInfo.setAutoPlay(true);
        }
    }


    public ShuiHuYeZiCardUserBattleInfo getPlayer1() {
        return player1;
    }

    public void setPlayer1(ShuiHuYeZiCardUserBattleInfo player1) {
        this.player1 = player1;
    }

    public ShuiHuYeZiCardUserBattleInfo getPlayer2() {
        return player2;
    }

    public void setPlayer2(ShuiHuYeZiCardUserBattleInfo player2) {
        this.player2 = player2;
    }
}
